/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.injectless_mocking;

import moved.org.objectweb.asm.MethodVisitor;
import picounit.features.classloader.mutator.Access;
import picounit.features.classloader.mutator.DefaultClassMutator;

public class InjectlessMockingClassMutator extends DefaultClassMutator {
	private final SignatureMangler signatureMangler;

	public InjectlessMockingClassMutator(SignatureMangler signatureMangler) {
		super(new InjectlessMockingMethodMutator(signatureMangler));

		this.signatureMangler = signatureMangler;
	}

	@Override
	public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
		if (publicButNotStatic(new Access(access))) {
			addFlagToControlWhetherMethodIsMocked(methodName, desc);
		}

		return super.visitMethod(access, methodName, desc, signature, exceptions);
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	private boolean publicButNotStatic(Access access) {
		return access.isPublic() && !access.isStatic();
	}

	private void addFlagToControlWhetherMethodIsMocked(String methodName, String methodSignature) {
		addPublicStaticBooleanField(
			signatureMangler.methodSignatureToFieldName(methodName, methodSignature));
	}

	private void addPublicStaticBooleanField(String fieldName) {
		super.visitField(ACC_PUBLIC + ACC_STATIC, fieldName, "Z", null, null);
	}
}